package com.uziot.bucket.common.stream;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * @author shidt
 * @version V1.0
 * @className TryCatchStreamDemo
 * @date 2021-05-21 10:48:42
 * @description
 */

@Slf4j
public class TryCatchStreamDemo {

    /**
     * 不用写一大堆finally来关闭资源,所有实现Closeable的类声明都可以写在里面,最常见于流操作,socket操作,
     * 新版的httpclient也可以;
     * 需要注意的是,try()的括号中可以写多行声明,每个声明的变量类型都必须是Closeable的子类
     * 简洁的代码，但是有局限性，只有本类或父类的实现AutoCloseable接口才可以这样自动close流，
     * 常见的实现了此接口的类有字节流、字符流、SocketChannel等。
     */
    private static void afterJdk7(String data, String path, Long name) {
        File file;
        file = new File(path, name + ".txt");

        try (OutputStreamWriter ops = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
             BufferedWriter bw = new BufferedWriter(ops)) {
            bw.append("data:image/jpg;base64,").append(data);
        } catch (Exception e) {
            log.error("保存图片异常:{}", e.getMessage());
        }
    }

    /**
     * JDK1.7前的写法，常见写法
     * 1.包装流（处理流）和节点流关闭
     * 概念：
     * 如果一个流的构造方法中需要传入流，那么这传入流称为“节点流”，此处的OutputStreamWriter就是节点流。
     * 外部负责包装的流，称为：包装流，也可以叫做处理流，BufferedWriter就是包装流。
     * 关闭：
     * 包装流的关闭，只需要关闭包装流即可，包装流的close方法会自动将节点流也关闭。
     * 2.按顺序关闭流
     * 如果按顺序关闭流，是从内层流到外层流关闭还是从外层到内层关闭？
     * 一般情况下是：先打开的后关闭，后打开的先关闭
     * 另一种情况：看依赖关系，如果流a依赖流b，应该先关闭流a，再关闭流b
     * 例如处理流a依赖节点流b，应该先关闭处理流a，再关闭节点流b
     * 当然完全可以只关闭处理流，不用关闭节点流。处理流关闭的时候，会调用其处理的节点流的关闭方法
     * 如果将节点流关闭以后再关闭处理流，会抛出IO异常；
     */
    public static void beforeJdk7(String data, String path, Long name) {
        OutputStreamWriter ops = null;
        BufferedWriter bw = null;
        File file;
        try {
            file = new File(path, name + ".txt");
            ops = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
            bw = new BufferedWriter(ops);
            bw.append("data:image/jpg;base64,").append(data);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bw != null) {
                    bw.flush();
                    bw.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
